<?php

namespace app\common\logic;

use app\common\library\exception\ApiException;
use app\common\model\Bill;
use app\common\model\BillTitle;
use app\common\model\Order;
use fast\Nuo;
use think\db\Query;
use think\Env;
use think\Exception;
use think\Queue;

class BillLogic extends BaseLogic
{
    public $model;

    public $resourceHandle;

    public function assignModel()
    {
        $this->model          = new Bill();
    }

    public function handleSearch(Query $query, array $params): Query
    {
        if (isset($params['member_id'])) {
            $query->where('member_id', $params['member_id']);
        }
        if (isset($params['bill_id'])) {
            $query->where('id', $params['bill_id']);
        }
        if (isset($params['parent_id'])) {
            $query->where('parent_id', $params['parent_id']);
        }
        return $query;
    }

    /**
     * 开票确认
     * @param array $params
     * @return array
     * @throws ApiException
     */
    public function confirm(array $params)
    {
        try{
            $bill_title_info = BillTitle::get(['id'=>$params['bill_title_id'],'member_id'=>$params['member_id']]);
            if (empty($bill_title_info))
                throw new Exception('查无该发票抬头记录');
            $list = Order::where(['id'=>['in',$params['orders']]])->select()->toArray();
            if (empty($list)){
                throw new Exception('所选订单记录不存在');
            }
            foreach ($list as $v){
                if ($v['member_id'] != $params['member_id'])
                    throw new Exception("所选订单（ID：{$v['id']}）不是您名下订单，请重新选择！");
                if (!in_array($v['order_status'],[Order::ORDER_STATUS_WAIT_COMMENT,Order::ORDER_STATUS_OK]))
                    throw new Exception("所选订单（ID：{$v['id']}）暂不支持开票");
                if ($v['bill_id'] >0)
                    throw new Exception("所选订单（ID：{$v['id']}）已开票，请勿重复申请！");
            }
            $money = Order::where(['member_id'=>$params['member_id'],'order_status'=>['in',[Order::ORDER_STATUS_WAIT_COMMENT,Order::ORDER_STATUS_OK]],'id'=>['in',$params['orders']]])->sum('pay_amount');//计算总金额
            if ($money <=0)
                throw new Exception('订单金额需要大于0');
            return ['buyerName'=>$bill_title_info->buyerName,'type'=>$bill_title_info->type,'buyerTaxNum'=>$bill_title_info->buyerTaxNum,'email'=>$bill_title_info->email,'mobile'=>$bill_title_info->mobile,'money'=>sprintf("%01.2f", $money)];
        }catch (Exception $e){
            throw new ApiException($e->getMessage());
        }
    }


    /**
     * 申请开票
     * @param array $params
     * @return array
     * @throws ApiException
     */
    public function add(array $params)
    {
        try{
            $bill_title_info = BillTitle::get(['id'=>$params['bill_title_id'],'member_id'=>$params['member_id']]);
            if (empty($bill_title_info))
                throw new Exception('查无该发票抬头记录');
            foreach ($params['orders'] as $v){
                $orderInfo = Order::where(['id'=>$v,'member_id'=>$params['member_id'],'bill_id'=>0,'order_status'=>['in',[Order::ORDER_STATUS_WAIT_COMMENT,Order::ORDER_STATUS_OK]]])->find();
                if (empty($orderInfo))
                    continue;
                if ($orderInfo->pay_amount <= 0)
                    continue;
                if ($orderInfo->bill_id > 0)
                    continue;
                $bill_info = Bill::where(['status'=>1,'member_id'=>$params['member_id'],'orderId'=>$v])->find();
                if (empty($bill_info)){
                    $bill_info = Bill::create([
                        'buyerName'=>$bill_title_info->buyerName,
                        'buyerTaxNum'=>$bill_title_info->buyerTaxNum,
                        'bill_money'=>sprintf("%01.2f", $orderInfo->pay_amount),
                        'email'=>$bill_title_info->email,
                        'mobile'=>$bill_title_info->mobile,
                        'openBlank'=>$bill_title_info->openBlank,
                        'buyerAccount'=>$bill_title_info->buyerAccount,
                        'buyerAddress'=>$bill_title_info->buyerAddress,
                        'buyerTel'=>$bill_title_info->buyerTel,
                        'member_id'=>$bill_title_info->member_id,
                        'status'=>1,
                        'orderNo'=>getOrderSn(),
                        'orderId'=>$v,
                    ]);
                    $orderInfo->bill_id = $bill_info->id;
                    $orderInfo->save();
                }
                Queue::push(\app\job\Bill::class,['member_id'=>$params['member_id'],'bill_id'=>$bill_info->id],'message');
            }
            return [];
        }catch (Exception $e){
            throw new ApiException($e->getMessage());
        }
    }


    /**
     * 开票历史
     * @param array $params
     * @return \think\Paginator
     * @throws ApiException
     */
    public function index(array $params)
    {
        try{
            $params['field'] = "id,createtime,bill_money,client_status";
            $params['orderBy'] = 'id';
            $params['orderType'] = 'desc';
            $params['parent_id'] = 0;
            return $this->getPageList($params)->each(function (&$item){
                if (in_array($item['client_status'],[0])){
                    $item['status'] = 0;//开票中
                }elseif (in_array($item['client_status'],[1])){
                    $item['status'] = 1;//开票成功
                }elseif (in_array($item['client_status'],[2])){
                    $item['status'] = 2;//发票作废
                }elseif (in_array($item['client_status'],[3])){
                    $item['status'] = 3;//开票失败
                }elseif (in_array($item['client_status'],[4])){
                    $item['status'] = 4;//发票作废中
                }
                $item['name'] = '电子发票';
                return $item;
            });
        }catch (Exception $e){
            throw new ApiException($e->getMessage());
        }
    }


    /**
     * 发票详情
     * @param array $params
     * @return \think\Paginator
     * @throws ApiException
     */
    public function detail(array $params)
    {
        try{
            $info = Bill::field('id,invoiceCode,invoiceNo,type,buyerName,client_status,orderId,buyerTaxNum,createtime,reason,bill_money,imgUrls,pdfUrl')->where(['member_id'=>$params['member_id'],'id'=>$params['bill_id']])->find();
            if ($info->client_status == 0){
                $info['status'] = 0;//开票中
            }elseif ($info->client_status == 1){
                $info['status'] = 1;//开票成功
            }elseif ($info->client_status == 2){
                $info['status'] = 2;//发票作废
            }elseif ($info->client_status == 3){
                $info['status'] = 3;//开票失败
            }elseif($info->client_status == 4){
                $info['status'] = 4;//发票作废中
            }
            return $info;
        }catch (Exception $e){
            throw new ApiException($e->getMessage());
        }
    }


    /**
     * 发票取消
     * @param array $params
     * @return array
     * @throws ApiException
     */
    public function cancel(array $params)
    {
        try{
            $bill_info = Bill::get(['id'=>$params['bill_id'],'member_id'=>$params['member_id']]);
            if (empty($bill_info))
                throw new Exception('查无该发票记录');
            if ($bill_info->client_status == 0)
                throw new Exception('发票开具中，请勿取消！');
            if ($bill_info->client_status == 2)
                throw new Exception('该发票已作废，请勿重复提交！');
            if ($bill_info->client_status == 4)
                throw new Exception('该发票作废中，请勿重复提交！');
            if ($bill_info->client_status == 3)
                throw new Exception('该发票开票失败，无需取消！');
            //红字确认单申请
            $nuo = new Nuo();
            $arr = $nuo->saveInvoiceRedConfirm([
                'orderNo'=>getOrderSn(),
                'blueInvoiceLine'=>'pc',
                'sellerTaxNo' => Env::get('nuonuo.Taxnum'),
                'blueElecInvoiceNumber'=>$bill_info->invoiceNo,//原发票发票号码
                'applySource'=>0,
                'buyerName'=>$bill_info->buyerName,
                'redReason'=>2
            ]);
            if ($arr['code'] == '0'){
                throw new Exception('第三方红字确认单申请接口请求失败');
            }elseif ($arr['code'] == 'E0000'){//红字确认单申请成功
                $bill_info->redBillId = $arr['result'];
                $bill_info->client_status = 4; //发票申请作废中
                $bill_info->save();
            }else{
                throw new Exception($arr['describe']);
            }
            return [];
        }catch (Exception $e){
            throw new ApiException($e->getMessage());
        }
    }


}